﻿using System;
using System.Linq;
using System.Collections.Generic;
using WaitLess.App.Services.Interfaces;
using WaitLess.Business.Model;
using WaitLess.Business.Services.Interfaces;

namespace WaitLess.App.Services
{
    public class DataCache : IDataCache
    {
        private readonly IMunicipalOfficeLoader _municipalOfficeLoader;
        private readonly object _lock = new object();

        private bool IsLoaded { get { return (_isDistrictshuizenLoaded && _isStadskantorenLoaded); } }
        private bool _isDistrictshuizenLoaded;
        private bool _isStadskantorenLoaded;

        public IEnumerable<MunicipalOffice> Districshuizen { get; private set; }
        public IEnumerable<MunicipalOffice> Stadskantoren { get; private set; }
        public string FoursquareAccessToken { get; set; }

        public DataCache(IMunicipalOfficeLoader municipalOfficeLoader)
        {
            if (municipalOfficeLoader == null) throw new ArgumentNullException("municipalOfficeLoader");

            _municipalOfficeLoader = municipalOfficeLoader;

            Districshuizen = new List<MunicipalOffice>();
            Stadskantoren = new List<MunicipalOffice>();
        }

        public void Load(Action completedCallback)
        {
            if (IsLoaded)
            {
                completedCallback();
                return;
            }

            _municipalOfficeLoader.GetDistrictshuizen(r => LoadDistrictshuizen(r, completedCallback));
            _municipalOfficeLoader.GetStadskantoren(r => LoadStadskantoren(r, completedCallback));
        }

        private void LoadDistrictshuizen(IEnumerable<MunicipalOffice> districtshuizen, Action receiveResult)
        {
            Districshuizen = districtshuizen.OrderBy(d => d.District).ToList();

            ReturnResult(true, _isStadskantorenLoaded, receiveResult);
        }

        private void LoadStadskantoren(IEnumerable<MunicipalOffice> stadskantoren, Action receiveResult)
        {
            Stadskantoren = stadskantoren.OrderBy(d => d.District).ToList(); ;

            ReturnResult(_isDistrictshuizenLoaded, true, receiveResult);
        }

        private void ReturnResult(bool isDistrictshuizenLoaded, bool isStadskantorenLoaded, Action receiveResult)
        {
            lock (_lock)
            {
                _isDistrictshuizenLoaded = isDistrictshuizenLoaded;
                _isStadskantorenLoaded = isStadskantorenLoaded;

                if (IsLoaded)
                    receiveResult();
            }
        }
    }
}
